package cn.relx.pet.service.impl;

import cn.relx.basic.config.BussinessException;
import cn.relx.basic.config.JmsConfig;
import cn.relx.basic.domain.Point;
import cn.relx.basic.rocket.SpringBootConsumer;
import cn.relx.basic.service.impl.BaseServiceImpl;
import cn.relx.basic.util.*;
import cn.relx.order.domain.OrderPetAcquisition;
import cn.relx.order.mapper.OrderPetAcquisitionMapper;
import cn.relx.org.domain.Employee;
import cn.relx.org.domain.Shop;
import cn.relx.org.mapper.ShopMapper;
import cn.relx.pet.domain.SearchMasterMsg;
import cn.relx.pet.domain.SearchMasterMsgAuditLog;
import cn.relx.pet.dto.AcceptDto;
import cn.relx.pet.dto.SearchMasterMsgRefuseLogDto;
import cn.relx.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.relx.pet.mapper.SearchMasterMsgMapper;
import cn.relx.pet.query.SearchMasterMsgQuery;
import cn.relx.pet.service.ISearchMasterMsgService;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author relx
 * @since 2022-11-01
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {

    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;

    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private OrderPetAcquisitionMapper orderPetAcquisitionMapper;

    @Autowired
    private SpringBootConsumer springBootConsumer;


    /**
     * 宠物寻主添加
     * @param searchMasterMsg
     * @return
     */
    @Override
    @Transactional
    public AjaxResult publish(SearchMasterMsg searchMasterMsg) {
        //保存数据
        searchMasterMsgMapper.add(searchMasterMsg);
        //校验参数 //失败保存失败日志
        iScheckLog(searchMasterMsg);

        iScheckSuccess(searchMasterMsg);
        //通过：该状态为审核通过
        //根据用户找到50公里范围店铺，找到就设置shopId，没有就不管
        //调用update方法修改
        searchMasterMsgMapper.update(searchMasterMsg);
        return AjaxResult.me().success();
    }

    @Override
    public PageList<SearchMasterMsg> findSerchMasterMsg(SearchMasterMsgQuery query) {
        Integer totals = searchMasterMsgMapper.queryBySerchMasterMsgCount(query);
        if (null == totals || 0 == totals){
            return new PageList<>(0,new ArrayList<>());
        }
        // 查询数据
        List<SearchMasterMsg> ts = searchMasterMsgMapper.findSerchMasterMsg(query);

        //方到返回里面
        return new PageList<>(totals,ts);
    }

    /**
     * 拒单,并保存拒单日志
     * @param id
     * @param employee
     */
    @Override
    @Transactional
    public void updateSerchMasterMsg(Long id, Employee employee) {
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(id);
        if (searchMasterMsg == null){
            throw new BussinessException("寻主消息为空，请重新操作！");
        }
        searchMasterMsg.setShopId(null);
        searchMasterMsgMapper.update(searchMasterMsg);
        // 4.@TODO 添加拒单日志，自己去做，我也不确定有没有表，没有就创建，如果做的好一点，还要让平台管理员审核，审核通过看情况扣不扣分
        SearchMasterMsgRefuseLogDto searchMasterDto = new SearchMasterMsgRefuseLogDto();
        searchMasterDto.setMsgId(searchMasterMsg.getId());
        searchMasterDto.setNode("拒单！");
        searchMasterDto.setOperatorId(employee.getId());
        searchMasterMsgMapper.addSearchMasterMsgRefuseLogDto(searchMasterDto);
    }

    /**
     * 接单
     * @param acceptDto
     * @param employee
     */
    @Override
    @Transactional
    public void accept(AcceptDto acceptDto, Employee employee) {
        //查询寻主信息
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(acceptDto.getMsgId());
        //判断寻主信息是否为null
        if(searchMasterMsg == null){
            throw new BussinessException("寻主信息为空，请重新操作");
        }
        //解决线程安全问题

            synchronized (searchMasterMsg.getId()){
                if(employee == null){
                    throw new BussinessException("该员工不存在!");
                }
                if(searchMasterMsg.getState() == 1 && employee.getShopId().equals(searchMasterMsg.getShopId())){
                    searchMasterMsg.setState(2);
                    searchMasterMsgMapper.update(searchMasterMsg);
                    springBootConsumer.setId(searchMasterMsg.getId());
                    OrderPetAcquisition orderPetAcquisition = generateOrder(acceptDto, searchMasterMsg, employee);
                    producer(orderPetAcquisition.getId());
//                  Consumer(searchMasterMsg,acceptDto,employee);
                }
            }

        //判断state是否为1，并且shopId是否为当前店铺id
        //生成订单
    }

    private void producer(Long id){
        // 1.创建生产者对象，指定生产者组名

        try {
            DefaultMQProducer defaultMQProducer = new DefaultMQProducer("pet_group_order");
            // 2.连接mq
            defaultMQProducer.setNamesrvAddr(JmsConfig.NAME_SERVER);
            // 3.启动生产者
            defaultMQProducer.start();
            // 4.发送消息
            // 4.1.创建消息体
            // topic：消息主题 tags：此主题下的二级分类 body：消息的字节
            Message mes = new Message("order_topic", "pet_tag",id.toString().getBytes());
            // 4.2.发送消息
            mes.setDelayTimeLevel(3);
            defaultMQProducer.send(mes);
        } catch (MQClientException e) {
            e.printStackTrace();
        } catch (RemotingException e) {
            e.printStackTrace();
        } catch (MQBrokerException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 4.3.打印消息发送结果
        // 5.关闭生产者
//        sync_group_name.shutdown();


    }

//    private void Consumer(SearchMasterMsg searchMasterMsg,AcceptDto acceptDto, Employee employee) throws MQClientException {
//        // 1.创建默认推送消费者对象
//        DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(JmsConfig.TOPIC);
//        // 设置NameServer的地址
//        consumer.setNamesrvAddr(JmsConfig.NAME_SERVER);
//
//        // 订阅一个或者多个Topic，以及Tag来过滤需要消费的消息
//        consumer.subscribe("order-xhr-topic", "pet-xhr-tag");
//
//
//        // 注册回调实现类来处理从broker拉取回来的消息
//        consumer.registerMessageListener(new MessageListenerConcurrently() {
//            @Override
//            public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
//                generateOrder(acceptDto,searchMasterMsg,employee,0);
//                try {
//                    if(msgs != null){
//                        generateOrder(acceptDto,searchMasterMsg,employee,-1);
//                    }
//                    // 标记该消息已经被成功消费
//                    return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
//                } catch (Exception e) {
//                    e.printStackTrace();
//                    return ConsumeConcurrentlyStatus.RECONSUME_LATER;
//                }
//            }
//        });
//        // 启动消费者实例
//        consumer.start();
//    }

    /**
     * 审核通过
     * @param searchMasterMsg
     */
    @Override
    public void process(SearchMasterMsg searchMasterMsg) {
        searchMasterMsg.setState(2);
        searchMasterMsgMapper.update(searchMasterMsg);
    }

    private OrderPetAcquisition generateOrder(AcceptDto acceptDto, SearchMasterMsg searchMasterMsg, Employee employee) {
        OrderPetAcquisition orderPetAcquisition = new OrderPetAcquisition();
        orderPetAcquisition.setAddress(searchMasterMsg.getAddress());
        orderPetAcquisition.setDigest(acceptDto.getNote());
        orderPetAcquisition.setLastcomfirmtime(new Date(System.currentTimeMillis()+ 3*24*60*60*1000));
        orderPetAcquisition.setState(0);
        orderPetAcquisition.setPrice(new BigDecimal(searchMasterMsg.getPrice()));
        orderPetAcquisition.setUserId(searchMasterMsg.getUserId());
        orderPetAcquisition.setShopId(employee.getShopId());
        orderPetAcquisition.setEmpId(employee.getId());
        orderPetAcquisition.setSearchMasterMsgId(searchMasterMsg.getId());
        orderPetAcquisition.setOrderSn(CodeGenerateUtils.generateOrderSn(acceptDto.getHandler()));
        orderPetAcquisitionMapper.add(orderPetAcquisition);
        return orderPetAcquisition;
    }

    /**
     * Ai参数校验
     * 获取店铺id
     * @param searchMasterMsg
     */
    private void iScheckSuccess(SearchMasterMsg searchMasterMsg) {
        if(StringUtils.isEmpty(searchMasterMsg.getPrice()) ||
            StringUtils.isEmpty(searchMasterMsg.getName())  ||
            StringUtils.isEmpty(searchMasterMsg.getAddress())
        ){
            throw new BussinessException("参数不能为空！");
        }
        Point point = DistanceUtil.getPoint(searchMasterMsg.getAddress());
        List<Shop> shops = shopMapper.findAll();
        Shop shopId = DistanceUtil.getNearestShop(point, shops);
        if(shopId != null){
        searchMasterMsg.setShopId(shopId.getId());
        }
    }

    /**
     * 参数校验
     * 保存违规信心到日志
     * @param searchMasterMsg
     */
    private void iScheckLog(SearchMasterMsg searchMasterMsg) {
        StringBuilder str = new StringBuilder().append(searchMasterMsg.getAddress())
                .append(searchMasterMsg.getName())
                .append(searchMasterMsg.getTitle())
                .append(searchMasterMsg.getCoatColor())
                .append(searchMasterMsg.getNote());
        SearchMasterMsgAuditLog AuditLog = new SearchMasterMsgAuditLog();
        if(!BaiduAuditUtils.TextCensor(str.toString())){
            AuditLog.setNote("违规信息,请到个人中心进行修改操作！");
            AuditLog.setMsgId(searchMasterMsg.getId());
            searchMasterMsgAuditLogMapper.add(AuditLog);
            throw new BussinessException("违规信息,请到个人中心进行修改操作！");
        }
    }
}
